#include "SVS_Meter.h"

///< real-time register
#define REL_REG_CURRENT     (0x06)
#define REL_REG_VLOT        (0x08)
#define REL_REG_ENERGY      (0x0D)
#define REL_REG_POWER       (0x0A)

///< calibration register
#define CAL_REG_WPCFG       0x32
#define CAL_REG_HFCONST     0x61
#define CAL_REG_QPHSCAL     0x58
#define CAL_REG_ADCCON      0x59
#define CAL_REG_PQSTART     0x5F
#define CAL_REG_GPHS1       0x6D
#define CAL_REG_GP1         0x50
#define CAL_REG_GQ1         0x51
#define CAL_REG_GS1         0x52

#define CAL_METER_WPCFG1    0xA6    ///< open write protect 50H ~ 7CH
#define CAL_METER_WPCFG2    0xBC    ///< open write protect 40H ~ 45H
#define CAL_METER_WPCFG3    0x00    ///< close write protect

#define CAL_EC         	    3200U
#define	VOLT_CONVERT_K      1       ///< need to calibration
#define	VOLT_CONVERT_B      1       ///< need to calibration

typedef struct{
     int32_t Curr;
    uint32_t Vot;
    uint32_t Power;
    uint32_t Energy;
}meter_rms_st;
meter_rms_st meter;

#define CURRENT_FACT    (100)
#define VOLTAGE_FACT    (100)
#define POWER_FACT      (10)
#define ENERGY_FACT     (10)


/*******************************************************************************
* Function Name  : meter_init
* Description    : 计量功能初始化
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
void meter_init(void)
{
    /* 串口初始化  */
    ht_meter_init();
}

/*******************************************************************************
* Function Name  : meter_cal_reg_init
* Description    : 校准寄存器初始化
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
void meter_cal_reg_init(void)
{
    ht_write_reg(CAL_REG_HFCONST, 0x14  );///< 0x14 HFConst(20 =7.12*0.0529*0.01832* 10^10/(3200*220*5))
    ht_write_reg(CAL_REG_QPHSCAL, 0xFF16);

    ///< need to calculate
    ///< phase
    ht_write_reg(CAL_REG_GPHS1, 0x0051);
    
    ///< Gain
    ht_write_reg(CAL_REG_GP1, 0x0853);
    ht_write_reg(CAL_REG_GQ1, 0x0853);
    ht_write_reg(CAL_REG_GS1, 0x0853);
    
    ///< PQStart
    ht_write_reg(CAL_REG_PQSTART, 0x01);///<1w

    ht_write_reg(CAL_REG_ADCCON,  0x00);///<adc gain     
}

/*******************************************************************************
* Function Name  : read_curr
* Description    : 读取电流
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
int32_t read_curr(void)
{
    int32_t val=0;
    
    if(TRUE==ht_read_reg(REL_REG_CURRENT, (uint32_t*)&val))
    {
        val = val * 0.00003049 * CURRENT_FACT;
    }
    else
    {
        val=0;
    }
    
    return val;
}

/*******************************************************************************
* Function Name  : read_voltage
* Description    : 读取电压
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
uint32_t read_voltage(void)
{
	int32_t val = 0;
    
    if(TRUE==ht_read_reg(REL_REG_VLOT, (uint32_t*)&val))
    {
        val = val * 0.0004370f * VOLTAGE_FACT;
    }
    else
    {
        val=0;
    }
	
	return (uint32_t)val;    
}

/*******************************************************************************
* Function Name  : read_energy
* Description    : 读取电能
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
uint32_t read_energy(void)
{
    uint32_t val=0;
    
    if(TRUE==ht_read_reg(REL_REG_ENERGY, (uint32_t*)&val))
    {
        val = val * ENERGY_FACT * 0.0003125f;  
    }
    else
    {
        
    }
    
    return val;
}

/*******************************************************************************
* Function Name  : read_power
* Description    : 读取功率
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
uint32_t read_power(void)
{
    uint32_t val=0;
    
    if(TRUE==ht_read_reg(REL_REG_POWER, (uint32_t*)&val))
    {
        val = val * POWER_FACT * 0.0003125f;  
    }
    else
    {
        
    }
    
    return val;    
}

/*******************************************************************************
* Function Name  : meter_read_all
* Description    : 读取实时数据
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
void meter_read_all(void)
{
    meter.Vot    = read_voltage();
    meter.Curr   = read_curr();
    meter.Energy = read_energy();
    meter.Power  = read_power();
}

extern uint8_t diag_get_st(void);

/*******************************************************************************
* Function Name  : meter_task
* Description    : 计量任务
* Input          : 
* Output         : None
* Return         : None
*******************************************************************************/
void meter_task(void *pvParameters)
{
    meter_init();
    meter_cal_reg_init();
    
    while(1)
    {
        meter_read_all();
//        if(TimeOut == MultipleTimeoutCheck(&BrigTime, 0, 0, 1000))
//        {
//            DBUG_PRINTF("电压: %d\r\n", read_voltage());
//            DBUG_PRINTF("电流: %d\r\n", read_curr()   );
//            DBUG_PRINTF("电能: %d\r\n", read_energy() );
//            DBUG_PRINTF("功率: %d\r\n", read_power()  );
//        }
        //tick = xTaskGetTickCount();
        //DBUG_PRINTF("meter task is run: %d\r\n", tick);
        vTaskDelay(200);
    }
}
